﻿@page "/article/{channelId}"
@using AdminShared.Models.Article

<Layout Style=" padding: 0 24px 24px;">
    <Breadcrumb Style="margin: 16px 0;">
        <BreadcrumbItem>返回上一页</BreadcrumbItem>
        <BreadcrumbItem>首页</BreadcrumbItem>
        <BreadcrumbItem>文章管理</BreadcrumbItem>
        <BreadcrumbItem>所有文章</BreadcrumbItem>
    </Breadcrumb>
    <Content Class="site-layout-background">

        <div style="margin-bottom:10px">
            <Button Icon="plus" Type="@ButtonType.Primary" OnClick="()=>EditArticle()">添加</Button>
        </div>
        <Table TItem="DtoArticle" DataSource="@pageList.List" Total="@pageList.Total" Loading="tableLoading" RemoteDataSource>

            <RowTemplate>
                <Column @bind-Field="@context.Title" Title="标题"></Column>
                <Column @bind-Field="@context.CategoryName" Title="类别"></Column>
                <Column @bind-Field="@context.IsRecommend" Title="是否推荐"></Column>
                <Column @bind-Field="@context.IsDisplay" Title="显示状态"></Column>
                <Column @bind-Field="@context.ClickCount" Title="点击量"></Column>
                <Column Field="@context.CreateTime.LocalDateTime" Format="yyyy-MM-dd HH:mm" Title="创建时间"></Column>
                <ActionColumn Title="操作">
                    <Space>
                        <SpaceItem>
                            <a @onclick="()=>EditArticle(context)">编辑</a>
                        </SpaceItem>
                        <SpaceItem>
                            <Popconfirm Title="确认要删除吗？"
                                        OnConfirm="_=>DeleteArticle(context.Id)"
                                        OkText="Yes"
                                        CancelText="No">
                                <a style="color:red">删除</a>
                            </Popconfirm>

                        </SpaceItem>
                    </Space>
                </ActionColumn>
            </RowTemplate>

            <PaginationTemplate>
                <div style="margin:15px 0;float:right">
                    <Pagination Total="@pageList.Total" PageSize="pageSize" Current="pageNum" ShowSizeChanger OnChange="PageChange" ShowQuickJumper ShowTotal="showTotal" />
                </div>
            </PaginationTemplate>

        </Table>

    </Content>
</Layout>


@{
    RenderFragment editFooter = @<Template>
        <Button OnClick="SaveArticle" Type="@ButtonType.Primary" Loading="@saveLoading">保存</Button>
        <Button OnClick="()=>isShowEditArticle=false" @key="@("back")">取消</Button>
    </Template>;
}


<Modal Title="文章信息" Style="width:1160px;" Visible="@isShowEditArticle" OnCancel="()=>isShowEditArticle=false" Footer="@editFooter">

    <Form @ref="@_editArticleForm" Model="@editArticle" LabelColSpan="2" WrapperColSpan="22" Class="ueditorBody">

        <Tabs Type="@TabType.Card">

            <TabPane Key="1" Tab="基本信息">

                <FormItem Label="所属栏目">
                    <TreeSelect TItem="DtoTreeSelect"  Style="width: 190px" DataSource="selectCategoryList" @bind-Value="@categoryId" Placeholder="请选择所属栏目" TreeDefaultExpandAll ChildrenExpression="node=>node.DataItem.Children" DisabledExpression="node=>node.DataItem.IsDisabled" TitleExpression="node=>node.DataItem.Title" KeyExpression="node=>node.DataItem.Key" IsLeafExpression="node=>node.DataItem.Children==null"></TreeSelect>
                </FormItem>

                <FormItem Label="标题">
                    <Input Placeholder="请输入标题" @bind-Value="@context.Title" style="width: 30em" />
                </FormItem>

                <FormItem Label="是否显示">
                    <Switch @bind-Value="@context.IsDisplay" CheckedChildren="是" UnCheckedChildren="否" />
                </FormItem>

                <FormItem Label="是否推荐">
                    <Switch @bind-Value="@context.IsRecommend" CheckedChildren="是" UnCheckedChildren="否" />
                </FormItem>

                <FormItem Label="排序">
                    <Input Placeholder="请输入排序值" Type="number" @bind-Value="@context.Sort" style="width: 190px" />
                </FormItem>

                <FormItem Label="点击量">
                    <Input Placeholder="请输入点击量" Type="number" @bind-Value="@context.ClickCount" style="width: 190px" />
                </FormItem>

                <FormItem Label="封面图">
                    <Upload Action="@(LocalStorage.GetItemAsString("appAPIURL")+"File/UploadFile?business=TArticle&key="+fileKey+"&sign=cover")"
                            Name="file"
                            Headers=headers
                            DefaultFileList="fileList"
                            ShowButton="fileList?.Count < 5"
                            ListType="picture-card"
                            OnPreview="(file)=> PreviewImg(file)"
                            OnRemove=" (file)=> DeleteImg(file)"
                            OnChange="StateHasChanged"
                            BeforeAllUploadAsync="((fileList) =>  BeforeUpload(fileList))">
                        <div>
                            <Icon Type="plus"></Icon>
                            <div className="ant-upload-text">上传</div>
                        </div>

                    </Upload>

                    <Modal Visible="isPreviewImg" Title="预览" OnCancel="()=> isPreviewImg=false" Footer="null" Style="width:55%">
                        <Image Src="@previewImgUrl" />
                    </Modal>
                </FormItem>

            </TabPane>

            <TabPane Key="2" Tab="详细内容" ForceRender="true">
                <FormItem Label="摘要">
                    <TextArea ShowCount MaxLength=255 Placeholder="不填写则自动截取内容前255字符" @bind-Value="@context.Digest" MinRows="4" MaxRows="6" style="width:50em;min-height:80px" />
                </FormItem>

                <FormItem Label="内容">
                    <TextArea Id="Content" @bind-Value="@context.Content" />
                </FormItem>
            </TabPane>

        </Tabs>

    </Form>
</Modal>


@code {

    private string categoryId;


    private Form<DtoEditArticle>? _editArticleForm;

    Dictionary<string, string> headers = new();

    bool isPreviewImg = false;
    string? previewImgUrl;
    long fileKey;
    bool saveLoading = false;
    List<UploadFileItem> fileList = new();

    [Parameter]
    public string? channelId { get; set; }

    List<DtoTreeSelect>? selectCategoryList;

    override protected void OnInitialized()
    {
        GetCategoryTreeList();

        var authorization = LocalStorage.GetItemAsString("Authorization");

        headers.Add("Authorization", "Bearer " + authorization);
    }

    override protected void OnParametersSet()
    {
        GetArticleList();
        GetCategoryTreeList();
    }



    async void GetCategoryTreeList()
    {
        var parentKVList = new List<DtoKeyValueChild>();


        var kvList = await Http.GetFromJsonAsync<List<DtoKeyValueChild>>("Article/GetCategoryTreeList?channelId=" + channelId);

        if (kvList != null)
        {
            parentKVList.AddRange(kvList);

            selectCategoryList = CategoryTreeConvert(parentKVList)!.ToList();

            Console.WriteLine(selectCategoryList);
        }

    }

    private IEnumerable<DtoTreeSelect>? CategoryTreeConvert(List<DtoKeyValueChild>? keyValueChildren)
    {
        return keyValueChildren?.Select(t => new DtoTreeSelect
            {
                Key = t.Key!.ToString()!,
                Title = t.Value!.ToString()!,
                Children = CategoryTreeConvert(t.ChildList),
                IsDisabled = false
            }).ToList();
    }

    bool tableLoading = false;
    int pageNum = 1;
    int pageSize = 10;
    DtoPageList<DtoArticle> pageList = new();

    async void GetArticleList()
    {
        tableLoading = true;
        var retData = await Http.GetFromJsonAsync<DtoPageList<DtoArticle>>("Article/GetArticleList?channelId=" + channelId + "&pageNum=" + pageNum + "&pageSize=" + pageSize);

        if (retData != null)
        {
            pageList = retData;
        }

        tableLoading = false;
        StateHasChanged();
    }

    void PageChange(PaginationEventArgs args)
    {
        if (pageNum != args.Page)
        {
            pageNum = args.Page;
        }

        if (pageSize != args.PageSize)
        {
            pageSize = args.PageSize;
        }

        GetArticleList();
    }
    Func<PaginationTotalContext, string> showTotal = pageList => $"共 {pageList.Total} 条";


    bool isShowEditArticle = false;
    DtoEditArticle editArticle = new();
    long articleId;


    async void EditArticle(DtoArticle? article = null)
    {

        editArticle = new();
        fileList = new();
        articleId = default;

        if (article != null)
        {

            fileKey = article.Id;

            articleId = article.Id;
            editArticle.CategoryId = article.CategoryId;

            categoryId = editArticle.CategoryId.ToString();

            editArticle.Title = article.Title;
            editArticle.Sort = article.Sort;
            editArticle.ClickCount = article.ClickCount;
            editArticle.Digest = article.Digest;
            editArticle.Content = article.Content;
            editArticle.IsDisplay = article.IsDisplay;
            editArticle.IsRecommend = article.IsRecommend;

            fileList = article.CoverImageList?.Select(t => new UploadFileItem
                {
                    Id = t.Key!.ToString(),
                    FileName = "coverImg.jpg",
                    Url = t.Value!.ToString(),
                    State = UploadState.Success
                }).ToList()!;
        }
        else
        {
            fileKey = await Http.GetFromJsonAsync<long>("Base/GetSnowflakeId");
            editArticle.IsDisplay = true;
            editArticle.Sort = 99;
        }


        GetCategoryTreeList();


        isShowEditArticle = true;

        StateHasChanged();

        await Task.Delay(200);

        JS.InvokeVoidAsync("InitUeditor", "Content", 370);

    }


    async void SaveArticle()
    {
        editArticle.Content = await JS.InvokeAsync<string>("GetUeditorContent", "Content");
        editArticle.CategoryId = long.Parse(categoryId);

        if (_editArticleForm!.Validate())
        {
            saveLoading = true;

            if (articleId == default)
            {
                using (var httpResponse = await Http.PostAsJsonAsync<DtoEditArticle>("Article/CreateArticle?fileKey=" + fileKey, editArticle))
                {
                    var createArticleId = httpResponse.Content.ReadAsStringAsync().Result;

                    Message.Success("添加成功");
                }
            }
            else
            {
                using (var httpResponse = await Http.PostAsJsonAsync<DtoEditArticle>("Article/UpdateArticle?articleId=" + articleId, editArticle))
                {
                    var updateArticleRet = httpResponse.Content.ReadAsStringAsync().Result;

                    if (bool.Parse(updateArticleRet))
                    {
                        Message.Success("编辑成功");
                    }
                }
            }

            saveLoading = false;

            GetArticleList();

            isShowEditArticle = false;
        }
    }


    async void DeleteArticle(long articleId)
    {
        using (var httpResponse = await Http.DeleteAsync("Article/DeleteArticle?id=" + articleId))
        {
            var retValue = httpResponse.Content.ReadAsStringAsync().Result;

            if (Convert.ToBoolean(retValue))
            {
                GetArticleList();
                Message.Success("删除成功");
            }
        }
    }


    void PreviewImg(UploadFileItem file)
    {
        isPreviewImg = true;
        previewImgUrl = file.Url;
    }

    async Task<bool> DeleteImg(UploadFileItem file)
    {
        using (var httpResponse = await Http.DeleteAsync("File/DeleteFile?id=" + file.Id))
        {
            var retValue = await httpResponse.Content.ReadAsStringAsync();

            if (Convert.ToBoolean(retValue))
            {
                fileList.Remove(file);

                return true;
            }
            else
            {
                return false;
            }
        }
    }


    async Task<bool> BeforeUpload(List<UploadFileItem> fileList)
    {
        foreach (var file in fileList)
        {
            string fileSign = "";

            using (var fileStream = await Http.GetStreamAsync(file.ObjectURL))
            {
                using System.Security.Cryptography.SHA256 sha256 = System.Security.Cryptography.SHA256.Create();
                fileSign = Convert.ToHexString(sha256.ComputeHash(fileStream));
            }

            var timeStr = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds().ToString();
            var authorization = LocalStorage.GetItemAsString("Authorization");
            var privateKey = authorization.Split(".").ToList().LastOrDefault();
            var requestUrl = "/api/File/UploadFile?business=TArticle&key=" + fileKey + "&sign=cover";

            var dataStr = privateKey + timeStr + requestUrl + "file" + fileSign;

            using System.Security.Cryptography.SHA256 shaa256 = System.Security.Cryptography.SHA256.Create();
            string dataSign = Convert.ToHexString(shaa256.ComputeHash(System.Text.Encoding.UTF8.GetBytes(dataStr)));

            headers.Remove("Token");
            headers.Remove("Time");
            headers.Add("Token", dataSign);
            headers.Add("Time", timeStr);
        }

        return true;
    }


}
